home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Games of Daze
/
Infomagic - Games of Daze (Summer 1995) (Disc 1 of 2).iso
/
djgpp
/
go32
/
fs
/
ed.c
< prev
next >
Wrap
C/C++ Source or Header
|
1995-03-23
|
9KB
|
325 lines
#include <std.h>
#include <stdio.h>
#include <stdlib.h>
#include <setjmp.h>
#include <go32.h>
#define far
#include "ed.h"
#include "paging.h"
#include "unassmbl.h"
#include "debug.h"
#include "syms.h"
/*
void movedata(int srcseg, int srcofs, int destseg, int destofs, int length);
*/
ExternalDebuggerInfo edi;
TSS a_tss;
AREAS areas[MAX_AREA];
int old_go32, remote;
char *sympath, *symname, *symext, *startup_file;
word32 dos_mem_lo, dos_mem_hi;
static TSS org_tss;
static int my_ds;
static int app_ds;
static int edi_seg;
static int edi_ofs;
/* -------------------------------------------------------------- */
static void
edi_init (void)
{
int i;
asm("movw $0xfe01,%ax");
asm("int $0x21");
asm("movl %edx,_edi_seg");
asm("movl %eax,_edi_ofs");
asm("xor %eax,%eax");
asm("movw %ds,%ax");
asm("movl %eax,_my_ds");
movedata(edi_seg, edi_ofs, my_ds, (int)(&edi), sizeof(edi));
movedata(edi.a_tss_seg, edi.a_tss_ofs, my_ds, (int)(&a_tss), sizeof(TSS));
memcpy (&org_tss, &a_tss, sizeof (TSS));
app_ds = a_tss.tss_ds;
movedata(edi.areas_seg, edi.areas_ofs, my_ds, (int)areas, sizeof(areas));
for (i=0; i<MAX_AREA; i++)
{
areas[i].first_addr -= edi.app_base;
areas[i].last_addr -= edi.app_base;
}
}
/* -------------------------------------------------------------- */
void run_child(void)
{
int i;
movedata(my_ds, (int)(&edi), edi_seg, edi_ofs, sizeof(edi));
movedata(my_ds, (int)(&a_tss), edi.a_tss_seg, edi.a_tss_ofs, sizeof(TSS));
asm("movw $0xfe00,%ax");
asm("int $0x21");
movedata(edi_seg, edi_ofs, my_ds, (int)(&edi), sizeof(edi));
movedata(edi.a_tss_seg, edi.a_tss_ofs, my_ds, (int)(&a_tss), sizeof(TSS));
movedata(edi.areas_seg, edi.areas_ofs, my_ds, (int)areas, sizeof(areas));
for (i=0; i<MAX_AREA; i++)
{
areas[i].first_addr -= edi.app_base;
areas[i].last_addr -= edi.app_base;
}
}
/* -------------------------------------------------------------- */
void re_start (void)
{ int i;
memcpy (&a_tss, &org_tss, sizeof (TSS));
app_ds = a_tss.tss_ds;
movedata(edi.areas_seg, edi.areas_ofs, my_ds, (int)areas, sizeof(areas));
for (i=0; i<MAX_AREA; i++)
{
areas[i].first_addr -= edi.app_base;
areas[i].last_addr -= edi.app_base;
}
}
/* -------------------------------------------------------------- */
static int invalid_addr(word32 a, unsigned len)
{
int i;
if ((int)invalid_addr > 0)
return 0;
for (i=0; i<MAX_AREA; i++)
if (a>=areas[i].first_addr && (a+len-1) <= areas[i].last_addr)
return 0;
if (a >= dos_mem_lo && a <= dos_mem_hi)
return 0;
printf("Invalid access to child, address %#lx length %#x\n", a, len);
if (can_longjmp)
longjmp(debugger_jmpbuf, 1);
return 1;
}
/* ---------------------------------------------------------------------- */
int
valid_addr (word32 vaddr, int len)
{ int a;
if (vaddr >= 0xffffffffl - len)
return 0;
len--;
for (a = 0; a < MAX_AREA; a++)
if ((vaddr + len <= areas[a].last_addr) && (vaddr >= areas[a].first_addr))
return 1;
if (vaddr >= dos_mem_lo && vaddr <= dos_mem_hi)
return 1;
return 0;
}
/* -------------------------------------------------------------- */
int read_child(word32 child_addr, void *buf, unsigned len)
{
if (invalid_addr(child_addr, len))
return 1;
if (child_addr >= dos_mem_lo && child_addr <= dos_mem_hi)
asm ("\n\
push %ecx\n\
push %esi\n\
push %edi\n\
movl 8(%ebp), %esi\n\
movl 12(%ebp), %edi\n\
movl 16(%ebp), %ecx\n\
cmpl $3, %ecx\n\
jbe L_ed_read_ch1\n\
shrl $2, %ecx\n\
rep\n\
movsl\n\
movl 16(%ebp), %ecx\n\
L_ed_read_ch1:\n\
andl $3, %ecx\n\
rep\n\
movsb\n\
pop %edi\n\
pop %esi\n\
pop %ecx\n\
");
else
movedata(app_ds, child_addr, my_ds, (int)buf, len);
return 0;
}
/* -------------------------------------------------------------- */
int write_child(word32 child_addr, void *buf, unsigned len)
{
if (invalid_addr(child_addr, len))
return 1;
if (child_addr >= dos_mem_lo && child_addr <= dos_mem_hi)
asm ("\n\
push %ecx\n\
push %esi\n\
push %edi\n\
movl 8(%ebp), %edi\n\
movl 12(%ebp), %esi\n\
movl 16(%ebp), %ecx\n\
cmpl $3, %ecx\n\
jbe L_ed_write_ch1\n\
shrl $2, %ecx\n\
rep\n\
movsl\n\
movl 16(%ebp), %ecx\n\
L_ed_write_ch1:\n\
andl $3, %ecx\n\
rep\n\
movsb\n\
pop %edi\n\
pop %esi\n\
pop %ecx\n\
");
else
movedata(my_ds, (int)buf, app_ds, child_addr, len);
return 0;
}
/* -------------------------------------------------------------- */
void ansi(int fg)
{
if (!edi.ansi_mode)
return;
printf("\033[%d;%dm", (fg & A_bold) ? 1 : 0, 30+(fg&7));
}
/* -------------------------------------------------------------- */
static void
setup_env (word32 addr)
{ char **envp, test;
int env_len, str_len, i;
word32 env_addr, str_addr;
read_child (addr, &env_addr, 4);
read_child (env_addr, &str_addr, 4);
for (env_len = 0; str_addr; env_len++)
read_child (env_addr + env_len * 4, &str_addr, 4);
envp = (char **)malloc ((env_len + 1) * sizeof (char *));
envp[env_len] = 0;
for (i = 0; i < env_len; i++)
{ read_child (env_addr + i * 4, &str_addr, 4);
if (str_addr)
{ read_child (str_addr, &test, 1);
for (str_len = 0; test; str_len++)
read_child (str_addr + str_len, &test, 1);
envp[i] = malloc (str_len + 1);
read_child (str_addr, envp[i], str_len);
envp[i][str_len] = 0;
} else
envp[i] = 0;
}
environ = envp;
}
/* -------------------------------------------------------------- */
static void
setup_param (char *fn)
{ char *cp;
int i, len;
old_go32 = 0;
remote = 0;
sympath = malloc (258);
strcpy (sympath, fn);
symname = strdup (fn);
symext = strdup ("sym");
startup_file = strdup ("/go32/ldbg.rc");
len = strlen (symname);
for (i = len - 1; (i > 0) && (i > len - 4) && (symname[i] != '.') &&
(symname[i] != '\\') && (symname[i] != '/') &&
(symname[i] != ':'); i--)
;
if (symname[i] != '.')
i = len;
symname[i] = 0;
strcpy (sympath, symname);
len = strlen (symname);
for (i = len - 1; (i > 0) && (i > len - 8) && (symname[i] != '\\') &&
(symname[i] != '/') && (symname[i] != ':'); i--)
;
if (sympath[i] == '/' || sympath[i] == '\\')
i++;
strcpy (symname, sympath + i);
sympath[i] = 0;
/* cp = 0;
if (envp)
{ len = 1;
for (i = 0; envp[i] && len; i++)
{ if (strncmp (envp[i], "LDBG=", 5) == 0)
{ cp = strdup (envp[i] + 5);
len = 0;
}
}
} */
cp = getenv ("LDBG");
if (cp)
{ while (1)
{ char sw[100];
char val[100];
if (sscanf(cp, "%s%n", sw, &i) < 1)
break;
cp += i;
if (stricmp(sw, "oldgo32") == 0)
old_go32 = 1;
else
{ val[0] = 0;
sscanf(cp, "%s%n", val, &i);
cp += i;
if (val[0] == 0)
break;
if (stricmp(sw, "sympath") == 0)
{ strcpy (sympath, val);
} else if (stricmp(sw, "symname") == 0)
{ if (symname) free(symname);
symname = strdup(val);
} else if (stricmp(sw, "symext") == 0)
{ if (symext) free(symext);
symext = strdup(val);
} else if (stricmp(sw, "startup") == 0)
{ if (startup_file) free(startup_file);
startup_file = strdup(val);
} else if (stricmp(sw, "remote") == 0)
remote = atol(val);
}
}
}
i = strlen (sympath);
if (i > 0)
if (sympath[i - 1] != '/' && sympath[i - 1] != '\\')
{ sympath[i] = '/';
sympath[i + 1] = 0;
}
if (!old_go32)
if (edi.com_port)
remote = edi.com_port;
if (remote < 0 || remote > 4)
remote = 0;
}
/* -------------------------------------------------------------- */
int main (void)
{ char *fn;
edi_init ();
setup_env (a_tss.tss_esp + 0x08);
dos_mem_lo = _go32_info_block.linear_address_of_primary_screen & 0xf0000000;
dos_mem_hi = dos_mem_lo + 0x0fffffff;
fn = (char *)malloc(edi.filename_len + 1);
movedata(edi.filename_seg, edi.filename_ofs, my_ds, (int)(fn), edi.filename_len+1);
/*
printf("text: %#08x - %#08x\n", areas[A_text].first_addr, areas[A_text].last_addr);
printf("data: %#08x - %#08x\n", areas[A_data].first_addr, areas[A_data].last_addr);
printf("bss: %#08x - %#08x\n", areas[A_bss].first_addr, areas[A_bss].last_addr);
*/
setup_param (fn);
syms_init(fn);
debugger();
return 0;
}
void *sbrk(int l)
{
extern int end;
static int sold = (int)&end;
sold += l;
return (void *)(sold-l);
}